from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QGroupBox,
                             QLineEdit, QComboBox, QPushButton, QTextEdit,
                             QLabel, QProgressBar, QListWidget, QListWidgetItem,
                             QCheckBox, QSpinBox, QFormLayout)
from PyQt6.QtCore import Qt, pyqtSignal, QTimer
from PyQt6.QtGui import QFont
from typing import List, Dict, Any
from loguru import logger
from datetime import datetime


class RecordingWidget(QWidget):
    """录制组件"""
    
    # 信号定义
    start_recording = pyqtSignal(str)  # 开始录制信号，传递URL
    stop_recording = pyqtSignal()      # 停止录制信号
    
    def __init__(self):
        super().__init__()
        self.is_recording = False
        self.recorded_actions: List[Dict[str, Any]] = []
        self.recording_timer = QTimer()
        self.recording_start_time = None
        
        self.init_ui()
        self.setup_connections()
    
    def init_ui(self):
        """初始化界面"""
        layout = QVBoxLayout(self)
        
        # 录制配置区域
        config_group = QGroupBox("录制配置")
        config_layout = QFormLayout(config_group)
        
        # URL输入
        self.url_input = QLineEdit()
        self.url_input.setPlaceholderText("输入要录制的网址，如: https://example.com")
        self.url_input.setText("https://")
        config_layout.addRow("目标网址:", self.url_input)
        
        # 浏览器选择
        self.browser_combo = QComboBox()
        self.browser_combo.addItems(["Chromium", "Firefox", "WebKit"])
        config_layout.addRow("浏览器:", self.browser_combo)
        
        # 录制选项
        options_layout = QHBoxLayout()
        
        self.headless_checkbox = QCheckBox("无头模式")
        self.headless_checkbox.setToolTip("在后台运行浏览器，不显示界面")
        options_layout.addWidget(self.headless_checkbox)
        
        self.auto_wait_checkbox = QCheckBox("自动等待")
        self.auto_wait_checkbox.setChecked(True)
        self.auto_wait_checkbox.setToolTip("在动作之间自动添加等待时间")
        options_layout.addWidget(self.auto_wait_checkbox)
        
        self.wait_time_spinbox = QSpinBox()
        self.wait_time_spinbox.setRange(100, 5000)
        self.wait_time_spinbox.setValue(500)
        self.wait_time_spinbox.setSuffix(" ms")
        self.wait_time_spinbox.setToolTip("动作之间的等待时间")
        options_layout.addWidget(QLabel("等待时间:"))
        options_layout.addWidget(self.wait_time_spinbox)
        
        options_layout.addStretch()
        config_layout.addRow("选项:", options_layout)
        
        layout.addWidget(config_group)
        
        # 录制控制区域
        control_group = QGroupBox("录制控制")
        control_layout = QVBoxLayout(control_group)
        
        # 控制按钮
        button_layout = QHBoxLayout()
        
        self.start_btn = QPushButton("开始录制")
        self.start_btn.setStyleSheet("QPushButton { background-color: #4CAF50; color: white; font-weight: bold; }")
        self.stop_btn = QPushButton("停止录制")
        self.stop_btn.setStyleSheet("QPushButton { background-color: #f44336; color: white; font-weight: bold; }")
        self.stop_btn.setEnabled(False)
        
        self.pause_btn = QPushButton("暂停")
        self.pause_btn.setEnabled(False)
        self.resume_btn = QPushButton("继续")
        self.resume_btn.setEnabled(False)
        
        button_layout.addWidget(self.start_btn)
        button_layout.addWidget(self.stop_btn)
        button_layout.addWidget(self.pause_btn)
        button_layout.addWidget(self.resume_btn)
        button_layout.addStretch()
        
        control_layout.addLayout(button_layout)
        
        # 录制状态
        status_layout = QHBoxLayout()
        
        self.status_label = QLabel("就绪")
        self.status_label.setStyleSheet("QLabel { color: #666; }")
        status_layout.addWidget(QLabel("状态:"))
        status_layout.addWidget(self.status_label)
        
        self.duration_label = QLabel("00:00")
        self.duration_label.setFont(QFont("monospace", 12))
        status_layout.addWidget(QLabel("录制时长:"))
        status_layout.addWidget(self.duration_label)
        
        self.action_count_label = QLabel("0")
        status_layout.addWidget(QLabel("动作数量:"))
        status_layout.addWidget(self.action_count_label)
        
        status_layout.addStretch()
        
        control_layout.addLayout(status_layout)
        
        layout.addWidget(control_group)
        
        # 录制动作列表
        actions_group = QGroupBox("录制的动作")
        actions_layout = QVBoxLayout(actions_group)
        
        self.actions_list = QListWidget()
        self.actions_list.setAlternatingRowColors(True)
        actions_layout.addWidget(self.actions_list)
        
        # 动作操作按钮
        action_buttons_layout = QHBoxLayout()
        
        self.clear_actions_btn = QPushButton("清空动作")
        self.export_actions_btn = QPushButton("导出动作")
        self.import_actions_btn = QPushButton("导入动作")
        
        action_buttons_layout.addWidget(self.clear_actions_btn)
        action_buttons_layout.addWidget(self.export_actions_btn)
        action_buttons_layout.addWidget(self.import_actions_btn)
        action_buttons_layout.addStretch()
        
        actions_layout.addLayout(action_buttons_layout)
        
        layout.addWidget(actions_group)
        
        # 录制日志
        log_group = QGroupBox("录制日志")
        log_layout = QVBoxLayout(log_group)
        
        self.log_text = QTextEdit()
        self.log_text.setMaximumHeight(100)
        self.log_text.setFont(QFont("monospace", 9))
        self.log_text.setReadOnly(True)
        log_layout.addWidget(self.log_text)
        
        layout.addWidget(log_group)
    
    def setup_connections(self):
        """设置信号连接"""
        # 控制按钮
        self.start_btn.clicked.connect(self.on_start_recording)
        self.stop_btn.clicked.connect(self.on_stop_recording)
        self.pause_btn.clicked.connect(self.on_pause_recording)
        self.resume_btn.clicked.connect(self.on_resume_recording)
        
        # 动作操作按钮
        self.clear_actions_btn.clicked.connect(self.clear_actions)
        self.export_actions_btn.clicked.connect(self.export_actions)
        self.import_actions_btn.clicked.connect(self.import_actions)
        
        # 录制计时器
        self.recording_timer.timeout.connect(self.update_recording_duration)
    
    def on_start_recording(self):
        """开始录制"""
        url = self.url_input.text().strip()
        if not url or not (url.startswith('http://') or url.startswith('https://')):
            self.add_log("错误: 请输入有效的URL")
            return
        
        try:
            self.is_recording = True
            self.recorded_actions.clear()
            self.actions_list.clear()
            self.recording_start_time = datetime.now()
            
            # 更新界面状态
            self.start_btn.setEnabled(False)
            self.stop_btn.setEnabled(True)
            self.pause_btn.setEnabled(True)
            self.status_label.setText("录制中...")
            self.status_label.setStyleSheet("QLabel { color: #4CAF50; font-weight: bold; }")
            
            # 启动计时器
            self.recording_timer.start(1000)  # 每秒更新一次
            
            # 发射开始录制信号
            self.start_recording.emit(url)
            
            self.add_log(f"开始录制: {url}")
            
        except Exception as e:
            self.add_log(f"启动录制失败: {str(e)}")
            self.reset_recording_state()
    
    def on_stop_recording(self):
        """停止录制"""
        try:
            self.is_recording = False
            
            # 停止计时器
            self.recording_timer.stop()
            
            # 更新界面状态
            self.reset_recording_state()
            self.status_label.setText("录制完成")
            self.status_label.setStyleSheet("QLabel { color: #2196F3; font-weight: bold; }")
            
            # 发射停止录制信号
            self.stop_recording.emit()
            
            duration = self.get_recording_duration()
            self.add_log(f"录制完成，共录制 {len(self.recorded_actions)} 个动作，耗时 {duration}")
            
        except Exception as e:
            self.add_log(f"停止录制失败: {str(e)}")
            self.reset_recording_state()
    
    def on_pause_recording(self):
        """暂停录制"""
        if self.is_recording:
            self.recording_timer.stop()
            self.pause_btn.setEnabled(False)
            self.resume_btn.setEnabled(True)
            self.status_label.setText("录制暂停")
            self.status_label.setStyleSheet("QLabel { color: #FF9800; font-weight: bold; }")
            self.add_log("录制已暂停")
    
    def on_resume_recording(self):
        """继续录制"""
        if self.is_recording:
            self.recording_timer.start(1000)
            self.pause_btn.setEnabled(True)
            self.resume_btn.setEnabled(False)
            self.status_label.setText("录制中...")
            self.status_label.setStyleSheet("QLabel { color: #4CAF50; font-weight: bold; }")
            self.add_log("录制已继续")
    
    def reset_recording_state(self):
        """重置录制状态"""
        self.start_btn.setEnabled(True)
        self.stop_btn.setEnabled(False)
        self.pause_btn.setEnabled(False)
        self.resume_btn.setEnabled(False)
    
    def add_action(self, action: Dict[str, Any]):
        """添加录制的动作"""
        try:
            self.recorded_actions.append(action)
            
            # 在列表中显示动作
            action_text = self.format_action_text(action)
            item = QListWidgetItem(action_text)
            item.setData(Qt.ItemDataRole.UserRole, action)
            self.actions_list.addItem(item)
            
            # 更新动作数量
            self.action_count_label.setText(str(len(self.recorded_actions)))
            
            # 自动滚动到底部
            self.actions_list.scrollToBottom()
            
            # 添加日志
            self.add_log(f"记录动作: {action_text}")
            
        except Exception as e:
            logger.error(f"添加动作失败: {e}")
    
    def format_action_text(self, action: Dict[str, Any]) -> str:
        """格式化动作文本"""
        action_type = action.get("type", "unknown")
        data = action.get("data", {})
        timestamp = action.get("timestamp", "")
        
        # 格式化时间戳
        if timestamp:
            try:
                dt = datetime.fromisoformat(timestamp.replace('Z', '+00:00'))
                time_str = dt.strftime("%H:%M:%S")
            except:
                time_str = timestamp[-8:] if len(timestamp) >= 8 else timestamp
        else:
            time_str = "00:00:00"
        
        if action_type == "navigate":
            return f"[{time_str}] 导航到: {data.get('url', '')}"
        elif action_type == "click":
            selector = data.get('selector', '')
            text = data.get('text', '')
            if text:
                return f"[{time_str}] 点击: {text} ({selector})"
            else:
                return f"[{time_str}] 点击: {selector}"
        elif action_type == "input":
            selector = data.get('selector', '')
            value = data.get('value', '')
            return f"[{time_str}] 输入: '{value}' -> {selector}"
        elif action_type == "keyboard":
            key = data.get('key', '')
            return f"[{time_str}] 按键: {key}"
        else:
            return f"[{time_str}] {action_type}: {str(data)}"
    
    def clear_actions(self):
        """清空动作列表"""
        self.recorded_actions.clear()
        self.actions_list.clear()
        self.action_count_label.setText("0")
        self.add_log("已清空所有动作")
    
    def export_actions(self):
        """导出动作"""
        if not self.recorded_actions:
            self.add_log("没有可导出的动作")
            return
        
        try:
            from PyQt6.QtWidgets import QFileDialog
            file_path, _ = QFileDialog.getSaveFileName(
                self, "导出录制动作", "recorded_actions.json", "JSON文件 (*.json)"
            )
            
            if file_path:
                import json
                with open(file_path, 'w', encoding='utf-8') as f:
                    json.dump(self.recorded_actions, f, ensure_ascii=False, indent=2, default=str)
                
                self.add_log(f"动作已导出到: {file_path}")
                
        except Exception as e:
            self.add_log(f"导出失败: {str(e)}")
    
    def import_actions(self):
        """导入动作"""
        try:
            from PyQt6.QtWidgets import QFileDialog
            file_path, _ = QFileDialog.getOpenFileName(
                self, "导入录制动作", "", "JSON文件 (*.json)"
            )
            
            if file_path:
                import json
                with open(file_path, 'r', encoding='utf-8') as f:
                    actions = json.load(f)
                
                self.recorded_actions = actions
                self.refresh_actions_list()
                self.add_log(f"已导入 {len(actions)} 个动作")
                
        except Exception as e:
            self.add_log(f"导入失败: {str(e)}")
    
    def refresh_actions_list(self):
        """刷新动作列表"""
        self.actions_list.clear()
        
        for action in self.recorded_actions:
            action_text = self.format_action_text(action)
            item = QListWidgetItem(action_text)
            item.setData(Qt.ItemDataRole.UserRole, action)
            self.actions_list.addItem(item)
        
        self.action_count_label.setText(str(len(self.recorded_actions)))
    
    def update_recording_duration(self):
        """更新录制时长"""
        if self.recording_start_time:
            duration = datetime.now() - self.recording_start_time
            total_seconds = int(duration.total_seconds())
            minutes = total_seconds // 60
            seconds = total_seconds % 60
            self.duration_label.setText(f"{minutes:02d}:{seconds:02d}")
    
    def get_recording_duration(self) -> str:
        """获取录制时长"""
        if self.recording_start_time:
            duration = datetime.now() - self.recording_start_time
            total_seconds = int(duration.total_seconds())
            minutes = total_seconds // 60
            seconds = total_seconds % 60
            return f"{minutes:02d}:{seconds:02d}"
        return "00:00"
    
    def add_log(self, message: str):
        """添加日志"""
        timestamp = datetime.now().strftime("%H:%M:%S")
        log_message = f"[{timestamp}] {message}"
        self.log_text.append(log_message)
        
        # 自动滚动到底部
        cursor = self.log_text.textCursor()
        cursor.movePosition(cursor.MoveOperation.End)
        self.log_text.setTextCursor(cursor)
        
        logger.info(message)
    
    def get_recorded_actions(self) -> List[Dict[str, Any]]:
        """获取录制的动作"""
        return self.recorded_actions.copy()
    
    def set_recording_config(self, browser_type: str = "chromium", headless: bool = False):
        """设置录制配置"""
        # 设置浏览器类型
        browser_map = {"chromium": 0, "firefox": 1, "webkit": 2}
        index = browser_map.get(browser_type.lower(), 0)
        self.browser_combo.setCurrentIndex(index)
        
        # 设置无头模式
        self.headless_checkbox.setChecked(headless)